package com.ant.collect.config;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.messaging.handler.HandlerMethod;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CustomAuthInterceptor extends SaInterceptor {
    /**
     * 请求到达控制器前的拦截逻辑
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1. 非 Controller 方法（如静态资源）直接放行
        if (!(handler instanceof HandlerMethod)) {
            return super.preHandle(request, response, handler);
        }

        // 2. 获取当前请求路径
        String requestPath = SaHolder.getRequest().getRequestPath();
        System.out.println("当前请求路径：" + requestPath);
        // 3. 验证登录状态（Token 有效性）
        // Token 无效/未登录会抛出 NotLoginException 异常
        // （注：Token 有效性与登录状态强关联，有效的 Token 必然对应已登录状态）
        if (needCheckLogin(requestPath)) { // 判断当前路径是否需要登录验证
            StpUtil.checkLogin(); // 验证登录，未登录则抛出异常
            System.out.println("登录验证通过，当前用户ID：" + StpUtil.getLoginId());
        }
        // 4. 验证角色（仅对需要角色验证的路径生效）
        if (needCheckRole(requestPath)) {
            // 例如：/admin/** 路径需要 "admin" 角色
            String requiredRole = getRequiredRole(requestPath); // 根据路径获取需要的角色
            StpUtil.checkRole(requiredRole); // 验证角色，不匹配则抛出异常
            System.out.println("角色验证通过，拥有角色：" + requiredRole);
        }

        // 5. 验证权限（仅对需要权限验证的路径生效）
        if (needCheckPermission(requestPath)) {
            // 例如：/user/delete 路径需要 "user:delete" 权限
            String requiredPermission = getRequiredPermission(requestPath); // 根据路径获取需要的权限
            StpUtil.checkPermission(requiredPermission); // 验证权限，不匹配则抛出异常
            System.out.println("权限验证通过，拥有权限：" + requiredPermission);
        }


        // 6. 所有验证通过，放行请求
        return super.preHandle(request, response, handler);
    }
    // -------------------------- 以下为辅助方法：判断路径是否需要验证及所需角色/权限 --------------------------

    /**
     * 判断当前路径是否需要登录验证
     */
    private boolean needCheckLogin(String path) {
        // 示例：除了 /login、/register、/public/** 之外的路径都需要登录
        return !(path.startsWith("/login")
                || path.startsWith("/register")
                || path.startsWith("/public/"));
    }

    /**
     * 判断当前路径是否需要角色验证
     */
    private boolean needCheckRole(String path) {
        // 示例：/admin/** 路径需要角色验证
        return path.startsWith("/admin/");
    }

    /**
     * 根据路径获取所需角色
     */
    private String getRequiredRole(String path) {
        // 示例：/admin/** 路径需要 "admin" 角色
        if (path.startsWith("/admin/")) {
            return "admin";
        }
        // 可根据业务扩展更多角色规则（如 /super/** 需要 "superAdmin" 角色）
        return "";
    }

    /**
     * 判断当前路径是否需要权限验证
     */
    private boolean needCheckPermission(String path) {
        // 示例：/user/delete、/user/update 等路径需要权限验证
        return path.startsWith("/user/delete")
                || path.startsWith("/user/update")
                || path.startsWith("/order/pay");
    }

    /**
     * 根据路径获取所需权限
     */
    private String getRequiredPermission(String path) {
        // 示例：路径与权限的映射关系
        if (path.startsWith("/user/delete")) {
            return "user:delete";
        }
        if (path.startsWith("/user/update")) {
            return "user:update";
        }
        if (path.startsWith("/order/pay")) {
            return "order:pay";
        }
        return "";
    }
}
